package com.ds.base.msg;

import com.ds.base.utils.CBTUtil;
import com.ds.persist.rule.IFormatRule;
import com.value.utils.DateUtil;
import net.sf.json.JSONObject;

import javax.validation.constraints.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;


/**
 * @author zhangyou
 */
public abstract class ACBTMsg {


    /**
     * 网关版本
     * 20071117020101
     * yyyyMMddHHmmss
     */
    protected String version = "v2.1";

    /**
     * 提交时间 20071117020101
     */
    protected String commitTime;

    /**
     * 代理商户代码
     */
//    @NotNull(message = "coName is null")
    protected String coName;

    /**
     * 企业代码
     */
//    @NotNull(message = "coCode is null")
    protected String coCode;



    /**
     * 流水号
     */
    protected String serialNumber;





    public ACBTMsg() {
        this.initSerialNumber();
        this.coName =CBTUtil.CONAME;
        this.coCode =CBTUtil.COCODE;
    }

    public String getCoName() {
        return coName;
    }

    public void setCoName(String coName) {
        this.coName = coName;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getCommitTime() {
        return commitTime;
    }

    public void setCommitTime(String commitTime) {
        this.commitTime = commitTime;
    }

    public String getCoCode() {
        return coCode;
    }

    public void setCoCode(String coCode) {
        this.coCode = coCode;
    }

    public String getSerialNumber() {
        return serialNumber;
    }

    public void setSerialNumber(String serialNumber) {
        this.serialNumber = serialNumber;
    }

    public JSONObject getBody() {
        return  this.msgToJson(this);
    }


    public abstract String getReqUrl();

    public Map<String, IFormatRule> getFormatRuleMap() {
        return null;
    }


    protected Map<String, Object> getData() {


        return null;
    }





    protected void initSerialNumber() {
        StringBuilder stringBuilder = new StringBuilder();
        //字符串 请求方生成唯一流水号 规则为 coCode(7 位) +YYYYMMDDHHMMS S(14 位)+5 位流水号
        stringBuilder.append(CBTUtil.COCODE).append(DateUtil.dateToString(new Date(), "YYYYMMDDHHMMSS"));
        Random random = new Random();
        int i = random.nextInt(99999) + 1;
        String randomString = String.format("%05d", i);
        stringBuilder.append(randomString);
        this.serialNumber = stringBuilder.toString();
    }

    @Override
    public String toString() {
        Map<String, Object> params = new HashMap<>();
        params.put("version", version);
        params.put("commitTime", commitTime);
        params.put("coName", coName);
        params.put("coCode", coCode);
        params.put("serialNumber", serialNumber);

        Map<String, Object> body = getBody();
        if(body!=null){
            params.putAll(body);
        }
        JSONObject jsonObject = JSONObject.fromObject(params);
        return jsonObject.toString();
    }

    private JSONObject msgToJson(ACBTMsg msg){

        //拿到cbtMsg 所有的字段
        Class<? extends ACBTMsg> msgClass = msg.getClass();
        Field[] fields = msgClass.getDeclaredFields();
        List<Field> fieldList = Arrays.asList(fields);

        JSONObject jsonObject = new JSONObject();
        fieldList.forEach((Field field) -> {
            String name = field.getName();
            if(name.equals("formatRuleMap")){
                return;
            }
            //获取属性的值
            try {
                //修改首字符大写 加get组成get方法
                StringBuilder sb = new StringBuilder();
                sb.append("get");
                sb.append(name.substring(0,1).toUpperCase()).append(name.substring(1));
                Method declaredMethod = msgClass.getDeclaredMethod(sb.toString());
                System.out.println(declaredMethod);
                Object value = declaredMethod.invoke(msg);
                //判断是否是需要格式化的字段
                Map<String, IFormatRule> formatRuleMap = msg.getFormatRuleMap();

                if(formatRuleMap!=null){
                    boolean b = formatRuleMap.containsKey(name);
                    IFormatRule iFormatRule = formatRuleMap.get(name);
                    if(b&&iFormatRule!=null){
                        Object o = iFormatRule.exeRule(value);
                        jsonObject.put(name,o);

                    }else{
                        jsonObject.put(name,value);
                    }
                }else{
                    jsonObject.put(name,value);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return jsonObject;
    }



}
